]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
authPrompt: Implement screen time ignore button
authorIgnacy Kuchciński <ignacykuchcinski@gnome.org>
Fri, 12 Dec 2025 01:32:45 +0000 (02:32 +0100)
committerFlorian Müllner <fmuellner@gnome.org>
Wed, 14 Jan 2026 14:41:48 +0000 (15:41 +0100)
Implement screen time ignore button which allows the parent to extend
the child’s computer time for the rest of the day.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/work_items/8578
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3999>

data/theme/gnome-shell-sass/widgets/_login-lock.scss
js/gdm/authPrompt.js

index d11d7224bc4f9e98f47e4d042a829ae7824ea8b1..5929ccc572d626315c1ea1758dfb4883a9569bb2 100644 (file)
@@ -271,6 +271,16 @@ $_gdm_dialog_width: 25em;
   .parental-controls-shield-description {
     text-align: center;
   }
+
+  .parental-controls-shield-button {
+    margin-top: 0.85em;
+    @extend %lockscreen_button;
+    @extend %title_4;
+    padding: $base_margin * 4 $base_margin * 11;
+    color: $_gdm_fg;
+    background-color: transparentize($_gdm_fg, .9);
+    border-radius: $forced_circular_radius;
+  }
 }
 
 // Notifications
index 4a9e4f67b34e0d9f12ea5234906c931678f13b6c..1486a97fca214080333746f139623db74821c979 100644 (file)
@@ -1,4 +1,5 @@
 import Clutter from 'gi://Clutter';
+import Gio from 'gi://Gio';
 import GLib from 'gi://GLib';
 import Atk from 'gi://Atk';
 import GObject from 'gi://GObject';
@@ -15,6 +16,11 @@ import * as ShellEntry from '../ui/shellEntry.js';
 import * as UserWidget from '../ui/userWidget.js';
 import {wiggle} from '../misc/animationUtils.js';
 
+import {loadInterfaceXML} from '../misc/fileUtils.js';
+
+const TimerChildIface = loadInterfaceXML('org.freedesktop.MalcontentTimer1.Child');
+const TimerChildProxy = Gio.DBusProxy.makeProxyWrapper(TimerChildIface);
+
 const DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
 const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1000;
 
@@ -29,6 +35,24 @@ class ParentalControlsShield extends St.BoxLayout {
             x_align: Clutter.ActorAlign.CENTER,
         });
 
+        this._requestExtensionCookie = null;
+
+        this._timerChildProxy = TimerChildProxy(Gio.DBus.system,
+            'org.freedesktop.MalcontentTimer1',
+            '/org/freedesktop/MalcontentTimer1',
+            (proxy, error) => {
+                if (error)
+                    console.error(`Failed to get TimerChild proxy: ${error}`);
+            },
+            null, /* cancellable */
+            Gio.DBusProxyFlags.DO_NOT_AUTO_START_AT_CONSTRUCTION
+        );
+
+        this._timerChildProxy.connectSignal('ExtensionResponse', (proxy, sender, params) =>
+            this._onExtensionResponse(proxy, sender, params));
+
+        this.connect('destroy', this._onDestroy.bind(this));
+
         this._titleLabel = new St.Label({
             style_class: 'parental-controls-shield-title',
             text: _('Screen Time Limit Reached'),
@@ -41,6 +65,45 @@ class ParentalControlsShield extends St.BoxLayout {
         });
         this._descriptionLabel.clutter_text.line_wrap = true;
         this.add_child(this._descriptionLabel);
+
+        this._ignoreButton = new St.Button({
+            style_class: 'parental-controls-shield-button',
+            // Translators: this is for ignoring a screen time limit for parental controls
+            label: _('Ignore'),
+            x_align: Clutter.ActorAlign.CENTER,
+        });
+        this._ignoreButton.connect('clicked',
+            () => this._onIgnoreButtonClicked().catch(logError));
+        this.add_child(this._ignoreButton);
+    }
+
+    _onDestroy() {
+        this._requestExtensionCookie = null;
+    }
+
+    async _onIgnoreButtonClicked() {
+        if (this._requestExtensionCookie)
+            return;
+
+        try {
+            [this._requestExtensionCookie] = await this._timerChildProxy.RequestExtensionAsync(
+                'login-session',
+                '',
+                0,
+                {},
+                Gio.DBusCallFlags.ALLOW_INTERACTIVE_AUTHORIZATION
+            );
+        } catch (e) {
+            console.warn(`Failed to obtain screen time extension: ${e.message}`);
+        }
+    }
+
+    _onExtensionResponse(proxy, sender, [_, cookie]) {
+        if (this._requestExtensionCookie === null ||
+            cookie !== this._requestExtensionCookie)
+            return;
+
+        this._requestExtensionCookie = null;
     }
 });